<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js">;(function () {
    // ------Class Creation------
    var initializing = false,
        fnTest = /xyz/.test(function () {
            xyz;
        }) ? /\b_super\b/ : /.*/;
    var OPTS_NAME = 'OPTS';
    var debug = false;
    // The base Class implementation (does nothing)
    this.Class = function () {
    };

    // Create a new Class that inherits from this class
    Class.extend = function (className, prop) {
        var _super = this.prototype;

        // Instantiate a base class (but only create the instance,
        // don't run the init constructor)
        initializing = true;
        var prototype = new this();
        initializing = false;

        // Copy the properties over onto the new prototype
        for (var name in prop) {

            var newPropVal = null;
            // 如果子类重写父类的方法
            if (typeof prop[name] == &quot;function&quot; &amp;&amp; typeof _super[name] == &quot;function&quot; &amp;&amp; fnTest.test(prop[name])) {
                newPropVal = (function (name, fn) {
                    return function () {
                        var tmp = this._super;

                        // Add a new ._super() method that is the same method
                        // but on the super-class
                        this._super = _super[name];

                        // The method only need to be bound temporarily, so we
                        // remove it when we're done executing
                        var ret = fn.apply(this, arguments);
                        this._super = tmp;

                        return ret;
                    };
                })(name, prop[name]);
            } else if (typeof prop[name] == &quot;function&quot;) { // 如果子类没有重写父类的方法,即新方法
                newPropVal = prop[name];
            } else if (name == OPTS_NAME) { // 如果是特定的属性对象
                // 拷贝对象
                var ret = {};

                ret = jQuery.extend({}, ret, _super[name] || {});

                ret = jQuery.extend({}, ret, prop[name]);

                newPropVal = ret;
            } else {
                newPropVal = prop[name];
            }

            prototype[name] = newPropVal;
        }

        // The dummy class constructor
        function Class() {
            // All construction is actually done in the init method
            if (!initializing &amp;&amp; this.init) {
                if (debug) {
                    try {
                        this.init.apply(this, arguments);
                    } catch (e) {
                        console.error(e);
                    }
                } else {
                    this.init.apply(this, arguments);
                }
            }
        }

        // Populate our constructed prototype object
        Class.prototype = prototype;

        // Enforce the constructor to be what we expect
        Class.prototype.constructor = Class;

        // And make this class extendable
        Class.extend = arguments.callee;

        // ------自定义方法------
        // 返回类名
        prototype.getClassName = function () {
            return className;
        }

        // ------自定义方法------
        /* 接口检查,参数可以是一个或多个,使用方法:
         * //声明接口
         * var Interface1 = Class.createInterface(['getName']);
         * // Person类实现接口
         * var Person = Class.extend({...}).impl(Interface1);
         */
        Class.impl = function () {
            if (arguments.length &gt; 0) {
                var _className = prototype.getClassName();
                for (var i = 0, len = arguments.length; i &lt; len; i++) {
                    var interfac = arguments[i];
                    if (!interfac._isInterfaceType) {
                        throw new Error(_className + &quot;.impl()第&quot; + (i + 1) + &quot;个参数必须是接口类型&quot;);
                    }
                    for (var j = 0, methodLen = interfac.methods.length; j &lt; methodLen; j++) {
                        var method = interfac.methods[j];
                        if (!prototype[method] || typeof prototype[method] !== &quot;function&quot;) {
                            throw new Error(&quot;类&quot; + _className + &quot;没有实现接口中的[&quot; + method + &quot;]方法&quot;);
                        }
                    }
                }
            }

            return Class;
        };// ------自定义方法 end------

        return Class;
    };// ------Class Creation end------

    // 辅助类
    var Interface = function (_methods) {
        if (arguments.length != 1) {
            throw new Error(&quot;创建接口参数只能有一个,并且为数组类型&quot;);
        }
        this.methods = [];
        this._isInterfaceType = true;

        for (var i = 0, len = _methods.length; i &lt; len; i++) {
            if (typeof _methods[i] !== &quot;string&quot;) {
                throw new Error(&quot;定义接口中的方法必须为字符串类型&quot;);
            }
            this.methods.push(_methods[i]);
        }
    }

    var id = 0;

    var JUI = {
        copy: function (o, c) {
            if (o &amp;&amp; c &amp;&amp; typeof c == 'object') {
                for (var p in c) {
                    o[p] = c[p];
                }
            }
            return o;
        }
        , copyNew: function (o, c) {
            var ret = {};
            if (o &amp;&amp; c &amp;&amp; typeof c == 'object') {

                for (var p in o) {
                    ret[p] = o[p];
                }

                for (var p in c) {
                    ret[p] = c[p];
                }
            }
            return ret;
        }
<span id='global-method-Interface'>        /**
</span>         * 创建接口
         * @param {String} className 类名
         * @param {Array} methods 接口方法列表
         */
        , Interface: function (className, methods) {
            var _interface = new Interface(methods);
            _interface.className = className;
            this[className] = _interface;
            return _interface;
        }
<span id='global-method-Class'>        /**
</span>         * 创建类
         * @param {String} className 类名
         * @param {Object} props 类方法
         * @param {Function} superClass 父类
         */
        , Class: function (className, props, superClass) {
            superClass = superClass || Class;

            var Clazz = superClass.extend(className, props);

            this[className] = Clazz;

            return Clazz;
        }
<span id='global-method-format'>        /**
</span>         * 格式化字符串
         * @example 用法:
         * JUI.format('{y}年{m}月{d}日',{y:'2010',m:'09',d:'15'});
         * 返回:2010年09月15日
         *
         * @param str 需要格式化的字符串
         * @param obj json数据
         * @return 返回格式化后的字符串
         */
        , format: function (str, obj) {
            for (var key in obj) {
                str = str.replace(new RegExp(&quot;\\{\\s*&quot; + key + &quot;\\s*\\}&quot;, &quot;g&quot;), obj[key]);
            }
            return str;
        }
        , log: function (s) {
            if (window.console) {
                this.log = function (s) {
                    console.log(s);
                }
            }
            this.log(s);
        }
<span id='global-method-getId'>        /**
</span>         * 获取唯一ID
         */
        , getId: function () {
            return id++;
        }
    }
    
    JUI.log('About JUI:https://gitee.com/durcframework/jui');
    
    window.JUI = JUI.copy(window.JUI || {}, JUI);

})();</pre>
</body>
</html>
